/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.mc.service.impl;

import com.xy.biz.mc.domain.bo.MessageBO;
import com.xy.biz.mc.domain.converter.MessageConverter;
import com.xy.biz.mc.domain.enums.MessageStatusEnum;
import com.xy.biz.mc.domain.query.MessageQuery;
import com.xy.biz.mc.domain.req.MultipleMessageRequest;
import com.xy.biz.mc.domain.resp.GetMessageResponse;
import com.xy.biz.mc.domain.resp.MessagePushResponse;
import com.xy.biz.mc.manager.MessageManager;
import com.xy.biz.mc.service.MessageService;
import com.xy.biz.mc.service.PushService;
import com.xy.lang.domain.Result;
import com.xy.tool.context.UserContextHolder;
import com.xy.tool.gid.service.GidService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import static com.xy.biz.mc.service.PushService.PREFIX_PUSH_SERVICE;

/**
 *
 *
 * @author zsp
 * @date 2021-2-25
 */
@Service
public class MessageServiceImpl implements MessageService {

	@Autowired
	private MessageManager messageManager;
	@Autowired
	private GidService gidService;
	@Autowired
	private Map<String, PushService> pushServiceMap;

	@Override
	public Result<MessagePushResponse> sendMessage(MessageBO messageBO) {
		messageBO.setSendTime(LocalDateTime.now());
		LocalDateTime now = LocalDateTime.now();
		buildMessageBO(messageBO, now);
		//推送的消息存入数据库备份
		int affectedRows = messageManager.saveMessage(messageBO);
		if (affectedRows > 0) {
			PushService pushService = pushServiceMap.get(PREFIX_PUSH_SERVICE + messageBO.getToType());
			if(null == pushService) {
				return Result.ofNotFound("未定义推送服务：", messageBO.getToType());
			}
			pushService.send(messageBO.getMessageId(), messageBO.getToId(), messageBO.getData());
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Override
	public Result<MessagePushResponse> sendAllMessage(Collection<MessageBO> collection) {
		LocalDateTime now = LocalDateTime.now();
		for(MessageBO messageBO : collection) {
			buildMessageBO(messageBO, now);
		}
		int affectedRows = messageManager.saveAllMessage(collection);
		if (affectedRows > 0) {
			PushService pushService;
			for(MessageBO messageBO : collection) {
				pushService = pushServiceMap.get(PREFIX_PUSH_SERVICE + messageBO.getToType());
				if(null == pushService) {
					return Result.ofNotFound("未定义推送服务：", messageBO.getToType());
				}
				pushService.send(messageBO.getMessageId(), messageBO.getToId(), messageBO.getData());
			}
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	private void buildMessageBO(MessageBO messageBO, LocalDateTime now) {
		messageBO.setMessageId(gidService.generate());
		messageBO.setStatus(MessageStatusEnum.SEND_SUCCESS.getCode());
		messageBO.setTenantId(UserContextHolder.getTenantId());
		messageBO.setCreateTime(now);
		messageBO.setUpdateTime(now);
	}

	@Override
	public Result<?> updateMessage(MessageBO messageBO) {
		messageBO.setUpdateTime(LocalDateTime.now());
		int affectedRows = messageManager.updateMessage(messageBO);
		if (affectedRows > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Override
	public Result<?> deleteMessage(Long messageId) {
		int affectedRows = messageManager.deleteMessage(messageId);
		if (affectedRows > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Override
	public MessageBO getMessage(Long messageId) {
		return messageManager.getMessage(messageId);
	}

	@Override
	public List<MessageBO> listMessageById(Collection<Long> collection) {
		return messageManager.listMessageById(collection);
	}

	@Override
	public List<GetMessageResponse> listMessage(MessageQuery query) {
		return messageManager.listMessage(query);
	}

	@Override
	public int countMessage(MessageQuery query) {
		return messageManager.countMessage(query);
	}

	@Override
	public Result<?> deleteMessageMultiple(MultipleMessageRequest request) {
		int row = messageManager.deleteMessageMultiple(request);
		if (row > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Override
	public Result<?> haveReadMultiple(MultipleMessageRequest request) {
		if (CollectionUtils.isEmpty(request.getMessageIds())) {
			request.setToId(UserContextHolder.getUserId());
		}
		int row = messageManager.haveReadMultiple(request);
		if (row > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

}
